package com.cherry.example.thread;
/*
线程的通讯： 一个线程完成了自己的任务，要通知另外一个线程做另外的任务。

线程通讯： 生产者与消费者。

需求： 要实现生成一个消费一个。


线程通讯涉及到方法：
	wait()     让当前线程进入以锁对象的监听器建立的线程池中等待。
	notify()   唤醒以锁对象的监听器建立的线程池中等待线程中的其中一个。
	notifyAll()   缓冲以锁对象建立的线程池中所有线程。

线程通讯通讯要注意的事项：
	1. wait() 、 notify()、 notifyAll() 这些方法全部都是属于Object类。
		原因：因为这些方法都要由锁对象调用，而锁对象可以是任意的对象。
		
	2. wait() 、 notify()、 notifyAll() 这些方法必须要在有锁的前提下才能调用，而且必须由锁对象去调动。 
		原因：因为要以锁对象建立一个线程池。
	
	3. 一个线程执行了wait（）方法会自动释放锁对象。


生成者与消费者都在同一个线程池中。



*/

public class ProducerCustomerDemo {
	
	public static void main(String[] args) {
		//创建一个产品对象
		Product p = new Product();
		//创建了线程对象
		Producer producer = new Producer(p);
		Customer customer = new Customer(p);
		//开启线程对象
		producer.start();
		customer.start();
		
		
	}

	//产品类
	static class Product{

		String name;

		int price;

		boolean flag ;	//是否生成完毕的标记。   默认是false（没有生成完毕）, true为生成完毕。
	}


	//生产者线程
	static class Producer extends Thread{

		Product p ; 	//产品


		public Producer(Product p){
			this.p = p;
		}

		@Override
		public void run() {
			int i = 0;
			while(true){
				synchronized (p) {
					if(p.flag==false){  //产品没有生成完毕
						if(i%2==0){
							p.name = "自行车";
							p.price = 300;
						}else{
							p.name = "摩托车";
							p.price = 5000;
						}
						System.out.println("生成者已经生成了"+p.name+" 价格是："+ p.price);
						i++;
						p.flag = true;
						//通知消费者去消费
						p.notifyAll();
					}else{ //生成完毕
						try {
							p.wait();  //生产者等待...

						} catch (InterruptedException e) {
							e.printStackTrace();
						}

					}
				}
			}
		}
	}



	//消费者线程
	static class Customer extends Thread{

		Product p; //产品

		public Customer(Product p){
			this.p = p;
		}

		@Override
		public void run() {
			while(true){
				synchronized (p) {
					if(p.flag==true){
						System.out.println("消费者已经消费了"+ p.name+" 价格是："+ p.price);
						//消费完毕--通知生产者去生产。
						p.flag = false;
						p.notify();
					}else{
						//产品没有生成完毕
						try {
							p.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}


	}

}
